<template>
  <!-- 自学模式 -->
  <div class="sbodyd">
    <div class="mainboxgj" v-show="!mainpoint">
      <!-- 分2 -->
      <div class="mainboxleft">
        <!-- 10 -->
        <div class="mainlefttopbox">
          <div class="mainsera">
            <div class="xbannername" @click="goback">
              <icon-left /> {{ partsName }}
            </div>
            <div
              class="startbox"
              @click="startfn"
              v-if="!startshow && addbsshowlx"
              >开始练习</div
            >

            <div
              class="startbox"
              @click="startfns"
              v-if="startshow && addbsshowlx"
              >退出练习</div
            >
            <div
              class="startbox"
              @click="allclear"
              v-if="startshow && addbsshowlx"
              >清空作答</div
            >
            <div class="startboxs" v-if="startshow && addbsshowlx"
              >显示答案
              <a-switch v-model="state.showText" @change="toggleTextButton"
            /></div>
          </div>

          <div class="maintopright">
            <!-- <div class="czmainitem tool" @click="zoomIn">
              <img src="@/assets/images/fd.png" alt="" class="normal" />
              <img src="@/assets/images/fdac.png" alt="" class="active" />
            </div> -->
            <!-- <div class="czmainitem tool" @click="zoomOut">
              <img src="@/assets/images/sx.png" alt="" class="normal" />
              <img src="@/assets/images/sxac.png" alt="" class="active" />
            </div> -->

            <!-- new菜单 -->
            <div class="mentsshow" @click="mainpoint = true">
              <img src="@/assets/images/serch.png" alt="" class="mentsimg" />
            </div>
            <div class="mentsshow" @click="mentshow = !mentshow">
              <img src="@/assets/images/ment.png" alt="" class="mentsimg" />
            </div>
          </div>
        </div>
        <!-- 70 -->
        <div class="box" ref="box" id="canvasContainer">
          <canvas
            id="myCanvas"
            :width="hbwidth"
            :height="hbheight"
            :style="{
              cursor: myStyle,
              backgroundColor: atlasTypeName === '插画' ? '#ffff' : 'black',
            }"
          >
          </canvas>
          <!--           @mousedown="currentMode == 'drawing' ? startDrawing : null"
            @mouseup="currentMode == 'drawing' ? stopDrawing : null"
            @mousemove="currentMode == 'drawing' ? draws : null" -->
          <canvas
            v-show="isCanvasVisible"
            id="overlayCanvas"
            :width="hbwidth"
            :height="hbheight"
            ref="overlayCanvas"
            @touchstart="startDrawing"
            @touchend="stopDrawing"
            @touchmove="draws"
            @mousedown="startDrawing"
            @mouseup="stopDrawing"
            @mousemove="draws"
            @click="showTextInput"
            :style="{ cursor: currentCursorStyle }"
          >
          </canvas>
          <div class="overlayCanvastool" v-show="isCanvasVisible">
            <div class="overlayCanvastooitemd" @click="isCanvasVisible = false">
              <icon-left />返回</div
            >
            <div class="overlayCanvastooitem" @click="undo"
              ><img src="@/assets/images/cx.png" alt=""
            /></div>
            <div class="overlayCanvastooitem" @click="redo">
              <img src="@/assets/images/fy.png" alt=""
            /></div>
            <!-- <div class="overlayCanvastooitem" @click="clearOverlay">
              <img src="@/assets/images/fy.png" alt="" />
            </div> -->
            <div class="overlayCanvastooitem" @click="enableDrawingMode"
              ><img src="@/assets/images/hb.png" alt=""
            /></div>
            <div class="overlayCanvastooitem" @click="toggleEraser"
              ><img src="@/assets/images/xpc.png" alt=""
            /></div>

            <div class="overlayCanvastooitem" @click="tsshow = !tsshow"
              ><img src="@/assets/images/tsb.png" alt=""
            /></div>
            <div class="overlayCanvastooitem" @click="hbcshow = !hbcshow"
              ><img src="@/assets/images/hbc.png" alt=""
            /></div>
            <div class="tsbox" v-if="tsshow">
              <div
                v-for="(item, index) in brushColordata"
                :key="index"
                class="tsitem"
                @click="brushColorfn(item)"
                :style="{ backgroundColor: item }"
              ></div>
            </div>
            <div class="hbcbox" v-if="hbcshow">
              <div
                class="hbcitem"
                @click="(brushSize = item), (hbcshow = false)"
                v-for="item in brushSizedata"
                :style="{
                  border: item + 'px solid #ffffff',
                }"
              ></div>
            </div>
            <!-- <div
              class="overlayCanvastooitem"
              :class="currentMode == 'text' ? 'overlayCanvastooitems' : null"
              @click="enableTextMode"
              >T</div
            > -->
            <div class="overlayCanvastooitem" @click="downloadImage"
              ><img src="@/assets/images/save.png" alt=""
            /></div>

            <!-- <div>
              <input id="color" type="color" v-model="brushColor" />

              <input
                id="size"
                type="range"
                min="1"
                max="10"
                v-model="brushSize"
              />
            </div> -->
          </div>
          <div
            v-if="showInput"
            :style="inputStyle"
            class="text-input-container"
          >
            <input
              v-model="customText"
              @keydown.enter="addTextMarkerOnEnter"
              class="text-input"
              placeholder="输入要添加的文字"
              @focus="isInputActive = true"
              @blur="handleInputBlur"
            />
          </div>
        </div>
        <!--  5-->
        <div class="gnbottom">
          <div class="tool" @click="tagdcoms('-1')">
            <img src="@/assets/images/let.png" alt="" class="normal" />
            <img src="@/assets/images/let.png" alt="" class="active" />
          </div>
          <div class="mentox"
            >影像页数:<span>{{ findindex() + 1 }}/{{ imgsrc.length }}</span>
          </div>
          <div class="tool" @click="tagdcoms('1')">
            <img src="@/assets/images/rght.png" alt="" class="normal" />
            <img src="@/assets/images/rght.png" alt="" class="active" />
          </div>
        </div>
        <!-- 15 -->
        <div class="lbox" ref="gosroll" @scroll="getScrollPosition">
          <div
            v-for="(item, index) in imgsrc"
            :key="index"
            class="lboxitem"
            @click="tagdcom(item.medicineAtlasImgId, '')"
          >
            <img :src="`${base + item.imgUrl}`" />
            <div class="msx" v-if="item.medicineAtlasImgId == dcomid"></div>
          </div>
        </div>
      </div>

      <!-- 功能菜单new -->
      <div class="ctfiexd" v-if="mentshow">
        <div class="ctmain">
          <div class="cttopbox">
            <div class="cttop"
              >菜单
              <img
                src="@/assets/images/closenew.png"
                alt=""
                class="closenew"
                @click="mentshow = false"
              />
            </div>
          </div>
          <div class="ctmanbox">
            <div class="ctbox">
              <div class="sqbox anto">
                <img src="@/assets/images/sq.png" alt="" class="sqboximg" />
                <div class="sqname" @click="bookfn">加入我的书签</div>
                <!-- <a-switch
                  v-model="state.showText"
                  @change="toggleTextButton"
                  checked-color="#5F6D7C"
                /> -->
              </div>
            </div>
            <div class="ctboxnew">
              <div class="ctboxlabel">标记 </div>
              <div class="bjmenbox">
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname">局部标签</div>
                  <div class="anto">
                    <a-switch
                      v-model="jubushow"
                      @change="jubu()"
                      checked-color="#5F6D7C"
                  /></div>
                </div>
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname">画笔</div>
                  <div class="anto">
                    <a-switch
                      v-model="pzshow"
                      @change="pzfn()"
                      checked-color="#5F6D7C"
                  /></div>
                </div>
              </div>
            </div>
            <div class="ctboxnew">
              <div class="ctboxlabel">操作 </div>
              <div class="bjmenbox">
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname">单支滑动</div>
                  <div class="anto">
                    <a-switch v-model="oneshow" checked-color="#5F6D7C"
                  /></div>
                </div>
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname">双指缩放</div>
                  <div class="anto">
                    <a-switch v-model="isZooming" checked-color="#5F6D7C"
                  /></div>
                </div>
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname">图像拖动</div>
                  <div class="anto">
                    <a-switch v-model="tdflag" checked-color="#5F6D7C"
                  /></div>
                </div>
              </div>
            </div>
            <div class="ctboxnew">
              <div class="ctboxlabel">筛选 </div>
              <div class="bjmenbox">
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemnames">扫描方向</div>
                </div>
                <div class="bjmenboxitems">
                  <div class="sxbox">
                    <div
                      class="sxitem"
                      @click="changeimgclassfn('全部')"
                      :class="classificationName == '全部' ? 'sxitemac' : ''"
                      >全部</div
                    >

                    <div
                      class="sxitem"
                      :class="
                        classificationName == item.classificationName
                          ? 'sxitemac'
                          : ''
                      "
                      v-for="item in imgclassdata"
                      @click="changeimgclassfn(item.classificationName)"
                      >{{ item.classificationName }}</div
                    >
                  </div>
                </div>
              </div>
              <div class="bjmenbox">
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemnames">加权</div>
                </div>
                <div class="bjmenboxitems">
                  <div class="sxbox">
                    <div
                      class="sxitem"
                      @click="changeimggroupfn('全部')"
                      :class="imggroupname == '全部' ? 'sxitemac' : ''"
                      >全部</div
                    >

                    <div
                      class="sxitem"
                      :class="imggroupname == item.typeName ? 'sxitemac' : ''"
                      v-for="item in imggroup"
                      @click="changeimggroupfn(item)"
                      >{{ item.typeName }}</div
                    >
                  </div>
                </div>
              </div>
            </div>
            <div class="ctboxnew">
              <div class="ctboxlabel">解剖部位 </div>
              <div class="bjmenbox">
                <div class="bjmenboxitem">
                  <div class="bjmenboxitemname"> 所有</div>
                  <div class="anto">
                    <a-switch
                      v-model="allflag"
                      @change="changecsd()"
                      v-if="optionsdata.length > 0"
                      checked-color="#5F6D7C"
                  /></div>
                </div>
                <div
                  class="bjmenboxitem"
                  v-for="(item, index) in optionsdata"
                  :key="index"
                  v-show="flagfn(item)"
                >
                  <div class="bjmenboxitemname">
                    {{ item.anatomicStructureName }}</div
                  >
                  <div class="anto">
                    <a-switch
                      v-model="item.flag"
                      @change="changecs(item)"
                      checked-color="#5F6D7C"
                  /></div>
                </div>
              </div>
            </div>
          </div>
          <div class="resetbox" @click="reset"> 重置 </div>
        </div>
      </div>
    </div>
    <!-- 知识点搜索 -->
    <div class="mainpoint" v-if="mainpoint">
      <div class="mainpointtop">
        <van-search
          v-model="markingPointsIdxz"
          shape="round"
          background="transparent"
          placeholder="请输入搜索关键词"
          @clear="handleSearch"
          @search="handleSearch"
          @update="handleSearch"
        >
          <template #left>
            <div @click="backfn" class="backfn"
              ><van-icon name="arrow-left"
            /></div>
          </template>
          <template #right-icon>
            <div style="color: black" @click="handleSearch(markingPointsIdxz)"
              >搜索&nbsp;&nbsp;</div
            >
          </template>
        </van-search>
      </div>
      <div class="mainpointbox" v-if="optionsselect.length > 0">
        <div
          class="mainpointitem"
          v-for="item in optionsselect"
          @click="changeselect(item.markingPointsId)"
        >
          {{ item.text }}</div
        >
      </div>
      <div class="mainpointbox" v-else>
        <img src="@/assets/images/qsl.png" alt="" />
        暂无数据
      </div>
      <!--          <a-select
              v-model="markingPointsIdxz"
              allow-search
              allow-clear
              :options="optionsselect"
              :style="{ width: '320px' }"
              placeholder="请输入"
              @search="handleSearch"
              :filter-option="false"
              :show-extra-options="false"
              :field-names="{ value: 'markingPointsId', label: 'text' }"
              @change="changeselect"
            /> -->
    </div>
    <!-- 知识点补充div -->
    <van-floating-panel
      v-model:height="height"
      v-if="visible"
      :lock-scroll="true"
      :content-draggable="false"
    >
      <img
        src="@/assets/images/closenew.png"
        alt=""
        class="zsboxclose"
        @click="visible = false"
      />
      <div class="zsbox">
        <div class="zsboxname">
          <div>{{ bwstuddata.pointName }}</div>
          <div class="zsboxnames">{{ bwstuddata.pointNameEng }}</div>
        </div>
        <div class="zsboxname zsboxnamee">
          <div>层次结构</div>
          <div class="zsboxnames">
            {{ bwstuddata.system }}> {{ bwstuddata.partsName }}>
            {{ bwstuddata.anatomicStructureName }}>
            {{ bwstuddata.pointName }}</div
          >
        </div>
        <div class="zsboxname zsboxnamee zsboxnameee">
          <div>定义</div>

          <div v-if="bwstuddata.pointContent != null">
            <!-- <div class="zsdkz" v-html="parsedContent"> </div
        >-->

            <div class="zsdkz">
              <v-md-preview :text="bwstuddata.pointContent"></v-md-preview>
            </div>
          </div>

          <div v-else>
            <div class="zsdkz">暂无知识点补充!</div>
          </div>
        </div>
      </div>
    </van-floating-panel>

    <!-- 加载页 -->
    <div class="loader-container" v-if="loding">
      <div class="loader"></div>
      <p class="pd">加载中</p>
    </div>

    <!-- 弹出填写试题答案的选择框 -->
    <a-modal
      v-model:visible="visiblest"
      @cancel="handleCancelst"
      :on-before-ok="handleBeforeOk"
      unmountOnClose
    >
      <template #title> 填写 </template>
      <div>
        <a-form :model="formModel">
          <a-form-item field="userText" label="答案">
            <a-input
              v-model="formModel.userText"
              placeholder="请输入答案"
              allow-clear
            />
          </a-form-item>
        </a-form>
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { marked } from 'marked';
  // @ts - nocheck
  import { defineProps, defineEmits, CSSProperties, computed } from 'vue';
  import { Message, Modal } from '@arco-design/web-vue';
  import {
    getPoint,
    getPointnew,
    getxqPoint,
    jpList,
    addbookMark,
    getPointjs,
  } from '@/api/tplist';
  import { storeToRefs } from 'pinia';
  import { useUserStore } from '@/store';
  import {
    defineComponent,
    reactive,
    ref,
    nextTick,
    onMounted,
    onBeforeUnmount,
    SetupContext,
  } from 'vue';
  import { showSuccessToast, showFailToast, buttonProps } from 'vant';

  const anchors = [
    400,
    Math.round(0.4 * window.innerHeight),
    Math.round(0.7 * window.innerHeight),
  ];
  const height = ref(anchors[0]);
  // 处理md
  const parsedContent = computed(() => {
    console.log('处理了');
    //
    // return marked.parse(
    //   '![](https://pandao.github.io/editor.md/images/logos/editormd-logo-180x180.png)'
    // );
    return marked.parse(bwstuddata.value.pointContent);
  });
  interface Marker {
    x: number;
    y: number;
    color: string;
    text?: string;
    textX: any;
    textY: any;
    markingPointsId: any;
  }
  const loding = ref(false);
  const props = defineProps<{
    partsName: string;
    imgsrc: [{ medicineAtlasImgId: 1; imgUrl: '' }];
    medicineAtlasId: string;
    imgclassdata: [{ classificationName: '' }];
    imggroup: [{ typeName: '' }];
    addbsshowlx: boolean;
    atlasTypeName: string;
  }>();
  const emit = defineEmits<{
    (event: 'goback'): void;
    (event: 'customEvent', payload: any): void; // 定义自定义事件
  }>();
  const mentshow = ref(false);
  const userStore = useUserStore();
  const userdata = storeToRefs(userStore);
  const studentId = ref(userdata.studentId.value);
  // 加入书签逻辑
  const bookfn = () => {
    addbookMark({
      studentId: studentId.value,
      medicineAtlasId: medicineAtlasId.value,
      medicineAtlasImgId: dcomid.value,
    }).then((res: any) => {
      if (res.code == 200) {
        showSuccessToast('成功');
      } else {
        showFailToast('失败');
      }
    });
  };
  // 加入书签逻辑结束
  // 定义图谱类型
  const atlasTypeName = ref('');
  atlasTypeName.value = props.atlasTypeName;
  // 练习兼容性代码s
  // 开始练习
  const toggleTextButton = () => {
    // state.showText = !state.showText;
    console.log('当前值', state.showText);
    draw('');
  };
  const startshow = ref(false);
  // 练习标识
  const addbsshowlx = ref(false);
  addbsshowlx.value = props.addbsshowlx;
  const allclear = () => {
    // 清空作答
    // 查询标记点为
    getPointnew({
      medicineAtlasId: medicineAtlasId.value,
      pageNum: 1,
      pageSize: 800,
    }).then((res: any) => {
      if (res.code == 200) {
        state.markers = [];
        saveMarkers();
        console.log('查询解刨点测试', res.data);
        const markersMap = new Map(
          state.markers.map((marker: any) => [
            marker.medicineAtlasImgId,
            marker,
          ])
        );

        for (const items of res.data) {
          try {
            // 输出调试信息
            // console.log('Processing item:', items);
            // console.log(
            //   'Extracted medicineAtlasImgId:',
            //   items.medicineAtlasImgId
            // );

            if (items.medicineAtlasImgId != null) {
              const existingMarker = markersMap.get(items.medicineAtlasImgId);
              const markingPointsObjects = JSON.parse(items.markingPoints);
              markingPointsObjects.medicineAtlasImgId =
                items.medicineAtlasImgId;

              markingPointsObjects.bsdata[0].markingPointsId =
                items.markingPointsId;
              markingPointsObjects.bsdata[0].flag = true;
              markingPointsObjects.bsdata[0].labels = true;
              markingPointsObjects.bsdata[0].anatomicStructureName =
                items.anatomicStructureName;
              markingPointsObjects.bsdata[0].anatomicStructureId =
                items.anatomicStructureId;

              if (existingMarker) {
                existingMarker.bsdata.push(...markingPointsObjects.bsdata);
              } else {
                markersMap.set(items.medicineAtlasImgId, markingPointsObjects);
              }
            }
          } catch (error) {
            console.error('Error processing item:', items, error);
          }
        }

        // 更新 state.markers
        state.markers = Array.from(markersMap.values());

        // 确保数据不为空
        if (state.markers.length === 0) {
          console.error('Final markers array is empty. Check input data.');
        } else {
          console.log('Final markers:', state.markers);
        }

        // console.log('打印获取的点位数据', state.markers);

        draw('');
        loding.value = false;
      }
    });
  };

  const startfn = () => {
    state.showText = false;
    startshow.value = true;
    draw('');
  };
  // 退出练习
  const startfns = () => {
    state.showText = true;
    startshow.value = false;
    draw('');
  };
  // 弹出
  const visiblest = ref(false);
  // 提交答案验证
  const handleBeforeOk = (done: any) => {
    console.log('查询点位验证', state.currentMarker, state.markers);

    state.markers.forEach((item: any) => {
      const itemsArray = item.medicineAtlasImgId.split(',').map(Number);
      if (itemsArray.includes(dcomid.value)) {
        item.bsdata.forEach((marker: any) => {
          if (state.currentMarker == marker) {
            marker.userText = formModel.value.userText;
            draw('');
            console.log('判断到当前相等修改然后保存缓存并且要执行draw', marker);
          }
        });
      }
    });

    visiblest.value = false;
    done(false);
    formModel.value.userText = '';
  };
  // 填写
  const handleCancelst = () => {
    visiblest.value = false;
    formModel.value.userText = '';
  };
  const formModel = ref({
    userText: '',
  });
  //练习兼容代码完成
  // 定义搜索成绩展示
  const markingPointsIdxz = ref();
  const optionsselect = ref<any[]>([]);
  const handleSearch = (e: any) => {
    optionsselect.value = [];
    // console.log('判断输入和框的', e);
    // 输入框输入的内容 是额
    state.markers.forEach((item: any) => {
      item.bsdata.forEach((items: any) => {
        if (items.text.includes(e)) {
          // state.hoveredMarker = items;
          optionsselect.value.push(items);
          console.log('模糊搜索后的展示', optionsselect.value);
        }
      });
    });
  };
  // 选择搜索结果后显示
  const changeselect = (e: any) => {
    // e 是markingPointsId  根据id 查找符合的 然后进行重新回话

    mainpoint.value = false;
    state.markers.forEach((item: any) => {
      item.bsdata.forEach((items: any) => {
        if (items.markingPointsId == e) {
          let firstPart = item.medicineAtlasImgId.split(',')[0];
          state.hoveredMarker = items;

          tagdcom(Number(firstPart), '搜索');
        }
      });
    });
  };
  // 搜索完成

  const visible = ref(false);

  const handleClick = () => {
    if (!addbsshowlx.value) {
      visible.value = true;
    } else {
      visiblest.value = true;
    }
  };
  const handleOk = () => {
    visible.value = false;
  };
  const handleCancel = () => {
    visible.value = false;
  };

  const imgsrc = ref<{ medicineAtlasImgId: number; imgUrl: string }[]>(
    props.imgsrc || []
  );

  const imgsrcs = ref(props.imgsrc);
  const imggroup = ref(props.imggroup);
  const imgclassdata = ref(props.imgclassdata);
  console.log('扫描方法', imggroup.value);

  const partsName = ref(props.partsName);
  // console.log('partsNamepartsName', partsName.value);

  const base = ref((window as any).config.VUE_APP_IMG_API);
  // console.log('Win', imgclassdata.value, imggroup.value);
  const medicineAtlasId = ref(props.medicineAtlasId);
  // console.log('接收到', imgsrc.value, base.value);
  const state = reactive({
    labels: null,
    showText: true,
    canBiaoZhu: false,
    pointColor: '#65FF00',
    pointSize: 7,
    // 手机端 1 然后设置间距搞点吧
    imgScale: 0.4,
    zoomStep: 0.1,
    markers: [] as { dcomid: number; bsdata: Marker[] }[],
    canvas: null as unknown as HTMLCanvasElement,
    ctx: null as CanvasRenderingContext2D | null,
    img: new Image(),
    // imgWidth: 1300,
    // imgHeight: 500,
    imgWidth: 480,
    imgHeight: 606,
    imgPosition: { x: 0, y: 0 },
    currentText: '',
    currentMarker: {},
    showLinesAndText: true,
    isDragging: false,
    startDragX: 0,
    startDragY: 0,
    imgOffsetX: 0,
    imgOffsetY: 0,
    isSpacePressed: false,
    hoveredMarker: null as Marker | null,
    editingMarker: false,
    editPanelX: 0,
    editPanelY: 0,
    addflag: false,
    flipHorizontal: false,
    flipVertical: false,
    rotation: 0, // 0, 90, -90
  });
  const markingPointsId = ref('');
  const dcomid = ref(1);
  dcomid.value = Number(localStorage.getItem('dcomid')) || 1;

  const goback = () => {
    emit('goback');
  };
  const flipHorizontald = () => {
    state.flipHorizontal = !state.flipHorizontal;
    draw('');
  };

  const flipVerticald = () => {
    state.flipVertical = !state.flipVertical;
    draw('');
  };

  const rotate90 = () => {
    state.rotation = (state.rotation + 90) % 360;
    draw('');
  };

  const rotateMinus90 = () => {
    state.rotation = (state.rotation - 90 + 360) % 360;
    draw('');
  };
  const checkHover = (x: number, y: number) => {
    state.hoveredMarker = null;
    myStyle.value = 'inherit';

    // 从状态中解构出相关的属性

    if (atlasTypeName.value == '插画') {
      state.imgScale = 0.2;
    }
    const { markers, pointSize, imgScale } = state;
    // 合并 bsdata
    const mergedBsdata = markers.filter((item: any) =>
      item.medicineAtlasImgId.includes(dcomid.value)
    );

    const targetElement = { bsdata: [] as Marker[] };

    targetElement.bsdata = mergedBsdata.flatMap((item) => item.bsdata);

    if (targetElement) {
      // 找到目标标记元素中的标记
      for (let marker of targetElement.bsdata) {
        // 获取画布和上下文
        const canvas = state.canvas!;
        const ctx = state.ctx!;

        // 计算缩放后的图像尺寸
        const scaledWidth = state.imgWidth * imgScale;
        const scaledHeight = state.imgHeight * imgScale;

        // 计算图像在画布上的偏移量
        const xOffset = (canvas.width - scaledWidth) / 2 + state.imgOffsetX;
        const yOffset = (canvas.height - scaledHeight) / 2 + state.imgOffsetY;

        // 计算标记的位置
        const markerX = marker.x * imgScale + xOffset;
        const markerY = marker.y * imgScale + yOffset;

        // 检查是否悬停在标记点上
        if (
          Math.hypot(x - markerX, y - markerY) <
          (pointSize / 2) * imgScale * 3
        ) {
          // console.log('悬停在标记');

          state.hoveredMarker = marker;
          myStyle.value = 'pointer';
          return true;
        }

        // 检查是否悬停在文本上
        const text = marker.text || '';
        ctx.font = `14px Arial`; // 根据实际使用的字体进行设置
        const textMetrics = ctx.measureText(text);
        const textWidth = textMetrics.width;

        const textX = marker.textX;
        const textY = marker.textY;
        const textHeight = 14 * imgScale;

        // 计算文本的边界框
        const textBoundingBox = {
          left: textX - textWidth,
          right: textX + textWidth,
          top: textY - textHeight,
          bottom: textY,
        };
        // console.log(
        //   '触发了点击判断',
        //   x,
        //   y,
        //   '-',
        //   marker.textX,
        //   marker.textY,
        //   textBoundingBox,
        //   marker.text,
        //   x >= textBoundingBox.left,
        //   x <= textBoundingBox.right,
        //   y >= textBoundingBox.top + 5,
        //   y <= textBoundingBox.bottom + 5
        // );
        // 修改了扩大范围
        if (
          x >= textBoundingBox.left &&
          x <= textBoundingBox.right &&
          y + 5 >= textBoundingBox.top &&
          y <= textBoundingBox.bottom + 5
        ) {
          myStyle.value = 'pointer';
          state.hoveredMarker = marker;
          // console.log('存在额叶');

          return true;
        }
      }
    }

    // 没有悬停在任何标记、线段或文本上
    state.hoveredMarker = null;
    return false;
  };

  const handleMouseMove = (e: MouseEvent | TouchEvent) => {
    // 判断是否为触摸事件
    const isTouchEvent = (e: MouseEvent | TouchEvent): e is TouchEvent =>
      'touches' in e;

    let canvasX: number, canvasY: number;
    // console.log('触摸事件', isTouchEvent(e));
    if (isTouchEvent(e)) {
      // 获取触摸事件的坐标
      const touch = e.touches[0];
      const rect = state.canvas!.getBoundingClientRect();
      canvasX = touch.clientX - rect.left;
      canvasY = touch.clientY - rect.top;
    } else {
      // 获取鼠标事件的坐标
      canvasX = e.offsetX;
      canvasY = e.offsetY;
    }

    if (state.isDragging) {
      dragMove(e);
    } else {
      // console.log('走触摸');

      checkHover(canvasX, canvasY);
      // draw('');
    }
  };
  const handleCanvasClick = (e: MouseEvent | TouchEvent) => {
    // console.log('当前是查询点击');

    let canvasX: number, canvasY: number;

    if ('touches' in e) {
      // 触摸事件
      const touch = e.touches[0];
      const rect = state.canvas!.getBoundingClientRect();
      canvasX = touch.clientX - rect.left;
      canvasY = touch.clientY - rect.top;
      checkHover(canvasX, canvasY);
      // 只有在需要阻止默认行为时调用
      e.preventDefault();
    } else {
      // 鼠标事件
      canvasX = e.offsetX;
      canvasY = e.offsetY;
    }
    // 添加标记的可以屏蔽掉
    if (state.canBiaoZhu) {
      // 计算图像坐标
      const imgX =
        (canvasX -
          (state.canvas!.width / 2 - (state.imgWidth * state.imgScale) / 2)) /
        state.imgScale;
      const imgY =
        (canvasY -
          (state.canvas!.height / 2 - (state.imgHeight * state.imgScale) / 2)) /
        state.imgScale;

      createMarker(imgX, imgY);
    } else if (state.hoveredMarker) {
      state.currentMarker = state.hoveredMarker;
      state.currentText = state.hoveredMarker.text || '';
      markingPointsId.value = state.hoveredMarker.markingPointsId;

      draw(state.hoveredMarker);

      if (startshow.value) {
        handleClick();
        return;
      }
      getxqPoint({ markPointsId: markingPointsId.value }).then((res: any) => {
        if (res.code === 200) {
          handleClick();
          bwstuddata.value = res.data;
          console.log('查询点位详情完成', res.data);
          // 再次查询点位知识点 中英文对照
          getPointjs({ pointName: res.data.pointName }).then((resd: any) => {
            bwstuddata.value.pointNameEng = resd.data.pointNameEng;
            bwstuddata.value.pointContent = resd.data.pointContent;
            console.log(
              '查询详情完成',
              bwstuddata.value.pointContent,
              resd.data.pointContent
            );
          });
        }
      });
    }
  };

  const bwstuddata = ref();
  const createMarker = (x: number, y: number) => {
    if (state.canBiaoZhu) {
      state.addflag = true;
      state.currentMarker = { x, y, color: state.pointColor };
      // draw('');
    }
  };

  const zoomIn = () => {
    state.imgScale += state.zoomStep;
    draw('');
  };

  const zoomOut = () => {
    if (state.imgScale > state.zoomStep) {
      state.imgScale -= state.zoomStep;
      draw('');
    }
  };

  const draw = (mbmarker: any) => {
    console.log('点击标记了', mbmarker);

    if (atlasTypeName.value == '插画') {
      state.imgScale = 0.2;
    }
    console.log('当前缩放比例', state.imgScale, atlasTypeName.value);
    // console.log('来自哪里的重绘', mbmarker);
    const canvas = state.canvas!;
    const ctx = state.ctx!;
    const img = state.img;
    if (state.imgWidth == 0) {
      return;
    }
    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    const scaledWidth = state.img.naturalWidth * state.imgScale;
    const scaledHeight = state.img.naturalHeight * state.imgScale;

    // 计算图像在画布上的偏移
    const xOffset = (canvas.width - scaledWidth) / 2 + state.imgOffsetX;
    const yOffset = (canvas.height - scaledHeight) / 2 + state.imgOffsetY;

    ctx.save();

    // 应用变换
    ctx.translate(canvas.width / 2, canvas.height / 2); // 移动到画布中心
    if (state.flipHorizontal) ctx.scale(-1, 1); // 水平翻转
    if (state.flipVertical) ctx.scale(1, -1); // 垂直翻转
    ctx.rotate((state.rotation * Math.PI) / 180); // 旋转
    ctx.translate(-canvas.width / 2, -canvas.height / 2); // 回到原位置

    // 绘制图像
    ctx.drawImage(img, xOffset, yOffset, scaledWidth, scaledHeight);

    // 恢复上下文状态为绘制标记做准备
    ctx.restore();
    ctx.save();

    // 重新应用变换
    ctx.translate(canvas.width / 2, canvas.height / 2);
    if (state.flipHorizontal) ctx.scale(-1, 1);
    if (state.flipVertical) ctx.scale(1, -1);
    ctx.rotate((state.rotation * Math.PI) / 180);
    ctx.translate(-canvas.width / 2, -canvas.height / 2);

    const margin = 70; // 从画布边缘的边距
    const textHeight = 14; // 文本高度
    const verticalSpacing = 5; // 文本之间的垂直间隔
    const textMargin = 20; // 文本与边缘的距离

    // 记录所有标记的位置和文本
    leftMarkers.value = [];
    rightMarkers.value = [];

    // 定义绘制标记和文本的函数
    const drawMarkersAndText = (markers: any[], isLeft: boolean) => {
      // console.log('继续执行');
      markers.forEach((item) => {
        const itemsArray = item.medicineAtlasImgId.split(',').map(Number);

        if (itemsArray.includes(dcomid.value)) {
          item.bsdata.forEach((marker: any) => {
            const markerX = marker.x * state.imgScale + xOffset;
            const markerY = marker.y * state.imgScale + yOffset;

            // 划分左右位置数组保存
            const count = leftMarkers.value.filter(
              (item: any) => item.flag == true
            ).length;
            const counts = rightMarkers.value.filter(
              (item: any) => item.flag == true
            ).length;

            // 根据位置将标记存入对应数组
            if (isLeft) {
              if (markerX < canvas.width / 2) {
                if (count > 23) {
                  leftMarkers.value.push(marker);
                } else {
                  marker.lintextshow = marker.flag;
                  leftMarkers.value.push(marker);
                }
              }
            } else {
              if (markerX >= canvas.width / 2) {
                if (counts > 23) {
                  marker.lintextshow = false;
                  rightMarkers.value.push(marker);
                } else {
                  marker.lintextshow = marker.flag;
                  rightMarkers.value.push(marker);
                }
              }
            }

            // 绘制标记点
            if (marker.flag) {
              ctx.fillStyle =
                marker == state.hoveredMarker ? '#409EFF' : '#' + marker.color;
              if (mbmarker == '搜索') {
                ctx.fillStyle =
                  marker == state.hoveredMarker
                    ? 'rgba(255, 0, 0, 1)'
                    : 'rgba(128, 128, 128, 0.5)';
              }
              ctx.beginPath();
              ctx.arc(markerX, markerY, state.pointSize / 2, 0, 2 * Math.PI);
              ctx.fill();
            }
          });
        }
      });
    };

    // 绘制左侧和右侧的标记
    drawMarkersAndText(state.markers, true); // 左侧标记
    drawMarkersAndText(state.markers, false); // 右侧标记

    // 左右数组优化调整顺序
    leftMarkers.value.sort((a: any, b: any) => a.y - b.y);
    rightMarkers.value.sort((a: any, b: any) => a.y - b.y);

    // 计算可用的文本区域
    const totalTextHeight =
      leftMarkers.value.length * (textHeight + verticalSpacing) -
      verticalSpacing; // 总共文本高度
    const availableHeight = canvas.height - 2 * textMargin;
    const startY = Math.max(
      textMargin,
      (availableHeight - totalTextHeight) / 2 + textMargin
    );

    // 计算每个文本的纵向位置并存放位置
    const calculateTextPositions = (markers: any, isLeft: any) => {
      let yPosition = startY;
      markers.forEach((marker: any) => {
        if (marker.flag && marker.lintextshow) {
          if (yPosition > 750 - 2 * textHeight) {
            // 超出最大高度
            marker.lintextshow = marker == mbmarker;
            if (marker.lintextshow) {
              marker.textY = leftMarkers.value[0].textY; // 显示文本
            }
          } else {
            marker.textY = yPosition;
            marker.lintextshow = true;
            yPosition += textHeight + verticalSpacing;
          }
        }
      });
    };

    // 计算左侧和右侧文本位置
    calculateTextPositions(leftMarkers.value, true);
    calculateTextPositions(rightMarkers.value, false);

    // 定义绘制文本和线条的函数
    const drawTextAndLines = (markers: any, isLeft: any) => {
      markers.forEach((marker: any, index) => {
        const { text, textY } = marker;
        const markerX = marker.x * state.imgScale + xOffset;
        const markerY = marker.y * state.imgScale + yOffset;
        const textX = isLeft ? margin : canvas.width - margin;

        if (marker.lintextshow && marker.flag && marker.labels) {
          ctx.strokeStyle =
            marker == state.hoveredMarker ? '#409EFF' : '#' + marker.color;
          if (mbmarker == '搜索') {
            ctx.strokeStyle =
              marker == state.hoveredMarker
                ? 'rgba(255, 0, 0, 1)'
                : 'rgba(128, 128, 128, 0.5)';
          }

          ctx.lineWidth = 1.5;
          ctx.beginPath();
          ctx.moveTo(markerX, markerY);

          // 确定线条结束点
          const lineEndX = isLeft
            ? Math.max(textX, margin)
            : Math.min(textX, canvas.width - margin);
          ctx.lineTo(lineEndX, textY);
          ctx.stroke();

          // 绘制文本
          ctx.fillStyle =
            marker == state.hoveredMarker ? '#409EFF' : '#' + marker.color;
          if (mbmarker == '搜索') {
            ctx.fillStyle =
              marker == state.hoveredMarker
                ? 'rgba(255, 0, 0, 1)'
                : 'rgba(128, 128, 128, 0.5)';
          }

          ctx.textAlign = isLeft ? 'right' : 'left';
          ctx.font = `${textHeight}px Arial`;

          // 显示答案
          if (state.showText) {
            // 显示答案和用户答案
            if (marker.userText) {
              ctx.fillText(
                marker.text + ' / ' + marker.userText || '',
                textX,
                textY
              );
            } else {
              // 只显示答案
              ctx.fillText(text, textX, textY);
            }
          } else {
            // 只显示用户写
            ctx.fillText(marker.userText || index + 1, textX, textY);
          }
          // ctx.fillText(text, textX, textY);

          // 更新状态
          state.markers.forEach((item: any) => {
            const itemsArray = item.medicineAtlasImgId.split(',').map(Number);
            if (itemsArray.includes(dcomid.value)) {
              item.bsdata.forEach((markers: any) => {
                if (markers.markingPointsId == marker.markingPointsId) {
                  markers.textX = textX;
                  markers.textY = textY;
                }
              });
            }
          });
        }
      });
    };

    // 绘制左侧和右侧的文本和线条
    drawTextAndLines(leftMarkers.value, true);
    drawTextAndLines(rightMarkers.value, false);

    // 恢复上下文状态
    ctx.restore();
    loding.value = false;
  };

  // 优化后的绘制函数

  const gosroll = ref();
  const getScrollPosition = () => {
    // console.log('获取到当前为止', gosroll);
    if (gosroll.value) {
      // console.log('获取到当前为止', gosroll.value.scrollLeft);

      return gosroll.value.scrollLeft;
    }
  };
  // console.log('Current Scroll Position:', getScrollPosition());
  // 保存
  const saveMarkers = () => {
    // localStorage.setItem('markers', JSON.stringify(state.markers));
    // draw('');
  };

  const loadMarkers = () => {
    const cachedMarkers = localStorage.getItem('markers');
    if (cachedMarkers) {
      state.markers = JSON.parse(cachedMarkers);
      draw('');
    }
  };

  const toggleLinesAndText = () => {
    state.showLinesAndText = !state.showLinesAndText;
    draw('');
  };

  // 增加条件开始判断
  const tdflag = ref(false);

  const startDrag = (e: MouseEvent | TouchEvent) => {
    if (!tdflag.value) {
      return;
    }
    console.log('当前拖动标记');
    // 判断是否为触摸事件
    const isTouchEvent = (e: MouseEvent | TouchEvent): e is TouchEvent =>
      'touches' in e;

    let clientX: number, clientY: number;

    if (isTouchEvent(e)) {
      // 触摸事件
      clientX = e.touches[0].clientX;
      clientY = e.touches[0].clientY;
      e.preventDefault(); // 仅在触摸事件时调用 preventDefault
    } else {
      // 鼠标事件
      clientX = e.clientX;
      clientY = e.clientY;
      if (e.button === 0) {
        e.preventDefault(); // 仅在左键点击时调用 preventDefault
      }
    }

    // 判断是否为左键点击或触摸
    if ((e instanceof MouseEvent && e.button === 0) || isTouchEvent(e)) {
      if (tdflag.value) {
        state.isDragging = true;

        // 获取 canvas 的位置和尺寸
        const rect = state.canvas!.getBoundingClientRect();
        console.log('Canvas rect:', rect); // 输出 rect 检查是否精确

        // 确保在计算开始位置时能处理动态变化
        state.startDragX = clientX - rect.left - state.imgOffsetX;
        state.startDragY = clientY - rect.top - state.imgOffsetY;
      }
    }
  };

  const stopDrag = () => {
    state.isDragging = false;
    tdflag.value = false;
  };
  const dragMove = (e: MouseEvent | TouchEvent) => {
    // 判断是否是鼠标事件还是触摸事件
    const clientX = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;
    const clientY = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;

    if (state.isDragging) {
      const rect = state.canvas!.getBoundingClientRect();
      state.imgOffsetX = clientX - rect.left - state.startDragX;
      state.imgOffsetY = clientY - rect.top - state.startDragY;
      draw('');
    }
  };

  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.code === 'Space') {
      state.isSpacePressed = true;
    }
  };

  const handleKeyUp = (e: KeyboardEvent) => {
    if (e.code === 'Space') {
      state.isSpacePressed = false;
    }
  };
  const tagdcom = (i: number, bs: any) => {
    state.imgWidth = 0;
    state.imgHeight = 0;
    const canvas = state.canvas!;
    const aspectRatio = state.img.naturalWidth / state.img.naturalHeight;
    const canvasAspectRatio = canvas.width / canvas.height;
    // 设置最大宽度和高度
    // const maxWidth = canvas.width * 0.999; // 画布宽度的99.9%
    // const maxHeight = canvas.height * 0.999; // 画布高度的99.9%

    // if (canvasAspectRatio > aspectRatio) {
    //   state.imgScale = Math.min(maxHeight / state.img.naturalHeight, 1);
    // } else {
    //   state.imgScale = Math.min(maxWidth / state.img.naturalWidth, 1);
    // }

    // 更新滚动位置和标志位
    getScrollPosition();
    flag.value = false;

    // 查找图片源并更新图片
    const imgsrcd = imgsrc.value.find((item) => item.medicineAtlasImgId === i);

    if (!imgsrcd) {
      return;
    }

    dcomid.value = i;
    //本地缓存  历史记录 图片id
    localStorage.setItem('dcomid', String(dcomid.value));
    localStorage.setItem('dcompage', String(findindex() + 1));

    // 确保图片允许跨域
    state.img.crossOrigin = 'anonymous';
    state.img.src = base.value + imgsrcd.imgUrl;

    state.img.onload = () => {
      // 获取 Canvas 的绘图上下文
      if (!state.ctx) {
        return;
      }
      // 清空画布并绘制图片
      // const ctx = state.ctx;
      state.ctx.drawImage(state.img, 0, 0, canvas.width, canvas.height);
      // ctx.drawImage(state.img, xOffset, yOffset, scaledWidth, scaledHeight);
      // 更新图片宽高
      state.imgWidth = state.img.width;
      state.imgHeight = state.img.height;
      // 调用绘制函数

      if (bs == '搜索') {
        draw('搜索');
      } else {
        draw('切换图片');
      }
    };
  };

  const optionsdata = ref([{ anatomicStructureName: '', flag: true }]);

  const tagdcoms = (i: any) => {
    console.log('i', i);

    const index = imgsrc.value.findIndex(
      (item) => item.medicineAtlasImgId == dcomid.value
    );
    if (i == 1) {
      if (imgsrc.value[index + 1]) {
        dcomid.value = imgsrc.value[index + 1].medicineAtlasImgId;
        tagdcom(dcomid.value, '');
      }
    } else if (i == -1) {
      if (imgsrc.value[index - 1]) {
        dcomid.value = imgsrc.value[index - 1].medicineAtlasImgId;
        tagdcom(dcomid.value, '');
      }
    } else if (i == 10) {
      if (imgsrc.value[index + 10]) {
        dcomid.value = imgsrc.value[index + 10].medicineAtlasImgId;
        console.log('imgsrc.value[index + 10]', imgsrc.value[index + 10]);

        tagdcom(dcomid.value, '');
      }
    } else if (i == -10) {
      if (imgsrc.value[index - 10]) {
        dcomid.value = imgsrc.value[index - 10].medicineAtlasImgId;
        tagdcom(dcomid.value, '');
      }
    }
  };
  const findindex = () => {
    return imgsrc.value.findIndex(
      (item) => item.medicineAtlasImgId == dcomid.value
    );
  };
  const handleWheel = (e: WheelEvent) => {
    e.preventDefault();
    if (e.deltaY < 0 && dcomid.value > 1) {
      const index = imgsrc.value.findIndex(
        (item) => item.medicineAtlasImgId == dcomid.value
      );
      if (imgsrc.value[index - 1]) {
        dcomid.value = imgsrc.value[index - 1].medicineAtlasImgId;
        tagdcom(dcomid.value, '');
      }
    } else {
      const index = imgsrc.value.findIndex(
        (item) => item.medicineAtlasImgId == dcomid.value
      );
      if (imgsrc.value[index + 1]) {
        dcomid.value = imgsrc.value[index + 1].medicineAtlasImgId;
        tagdcom(dcomid.value, '');
      }
    }
  };
  const jiegoudata = ref([]);
  const box = ref();
  const oneshow = ref(false);
  let startX = 0; // 触摸开始时的 X 坐标
  let startY = 0; // 触摸开始时的 Y 坐标
  let isSwiping = false; // 判断是否正在滑动
  let startTime = 0; // 触摸开始时的时间
  let threshold = 30; // 滑动阈值，决定是否视为有效滑动
  let fastSwipeThreshold = 200; // 快速滑动的最小时间（单位：毫秒）
  let fastSwipeDistance = 50; // 快速滑动的最小位移（单位：像素）
  let slowSwipeThreshold = 10; // 慢速滑动的最大位移（单位：像素）
  let slowSwipeTimeThreshold = 200; // 慢速滑动的最大时间阈值（单位：毫秒）

  // 用于判断快速滑动的标记
  let isFastSwipe = false;
  let hasMoved = false; // 判断是否已经滑动过

  // 处理水平滑动
  const handleSwipeHorizontal = (diffX: any) => {
    if (!oneshow.value) {
      return;
    }

    if (jubushow.value) {
      return;
    }

    if (diffX > 0) {
      tagdcoms('1'); // 向右滑动
    } else {
      tagdcoms('-1'); // 向左滑动
    }
  };

  // 处理垂直滑动
  const handleSwipeVertical = (diffY: any) => {
    if (!oneshow.value) {
      return;
    }
    if (jubushow.value) {
      return;
    }

    if (diffY > 0) {
      tagdcoms('1'); // 向下滑动
    } else {
      tagdcoms('-1'); // 向上滑动
    }
  };

  // 注册滑动开始事件
  const touchStartHandler = (e: any) => {
    if (!oneshow.value) {
      return;
    }
    if (jubushow.value) {
      return;
    }

    const touch = e.touches[0];
    startX = touch.clientX;
    startY = touch.clientY;
    startTime = Date.now(); // 记录滑动开始的时间
    isSwiping = true; // 开始滑动
    hasMoved = false; // 重置滑动标记
    isFastSwipe = false; // 每次开始滑动时，重置快速滑动标记
  };

  // 注册滑动移动事件
  const touchMoveHandler = (e: any) => {
    if (!oneshow.value) {
      return;
    }
    if (jubushow.value) {
      return;
    }

    if (!isSwiping) return;

    const touch = e.touches[0];
    const diffX = touch.clientX - startX; // X 轴偏移量
    const diffY = touch.clientY - startY; // Y 轴偏移量
    const currentTime = Date.now();
    const elapsedTime = currentTime - startTime; // 计算滑动的时间（毫秒）

    // 判断滑动的方向和速度
    if (Math.abs(diffX) > threshold || Math.abs(diffY) > threshold) {
      // 判断是否为快速滑动：时间大于 fastSwipeThreshold 且位移大于 fastSwipeDistance
      isFastSwipe =
        elapsedTime >= fastSwipeThreshold &&
        (Math.abs(diffX) >= fastSwipeDistance ||
          Math.abs(diffY) >= fastSwipeDistance);

      if (isFastSwipe) {
        // 如果是快速滑动，则直接处理
        if (Math.abs(diffX) > Math.abs(diffY)) {
          handleSwipeHorizontal(diffX);
        } else {
          handleSwipeVertical(diffY);
        }
      } else {
        // 标记已经开始滑动
        hasMoved = true;
      }
    }
  };

  // 注册滑动结束事件
  const touchEndHandler = (e: any) => {
    if (!oneshow.value) {
      return;
    }
    const touch = e.changedTouches[0];
    const diffX = touch.clientX - startX; // X 轴偏移量
    const diffY = touch.clientY - startY; // Y 轴偏移量
    const currentTime = Date.now();
    const elapsedTime = currentTime - startTime; // 计算滑动的时间（毫秒）

    // 判断是否是慢速滑动
    if (!isFastSwipe) {
      // 慢速滑动：滑动距离小，时间较短
      if (
        elapsedTime <= slowSwipeTimeThreshold &&
        Math.abs(diffX) <= slowSwipeThreshold &&
        Math.abs(diffY) <= slowSwipeThreshold
      ) {
        // 触发慢速滑动
        if (Math.abs(diffX) > Math.abs(diffY)) {
          handleSwipeHorizontal(diffX);
        } else {
          handleSwipeVertical(diffY);
        }
      } else if (hasMoved) {
        // 如果有滑动且没有快速滑动的条件，则触发慢速滑动
        if (Math.abs(diffX) > Math.abs(diffY)) {
          handleSwipeHorizontal(diffX);
        } else {
          handleSwipeVertical(diffY);
        }
      }
    }

    // 重置滑动状态
    isSwiping = false;
    hasMoved = false;
  };

  // 处理图片滑动完成
  // 触摸开始事件处理函数
  // function handleTouchStart(e: { touches: string | any[] }) {
  //   if (e.touches.length === 2 && isZooming.value) {
  //     // 记录两个手指的初始位置
  //     initialTouches = [e.touches[0], e.touches[1]];
  //     initialDistance = getDistance(initialTouches[0], initialTouches[1]);
  //   }
  // }
  // 双指检测
  // 假设你已经定义了 state 和 draw 函数
  let initialDistance = 0; // 初始两指间距离
  let initialTouches: any[] = []; // 记录初始两个手指的位置
  const isZooming = ref(false); // 用于存储是否开始放大

  // 计算两点间的距离
  function getDistance(
    touch1: { clientX: number; clientY: number },
    touch2: { clientX: number; clientY: number }
  ) {
    const dx = touch2.clientX - touch1.clientX;
    const dy = touch2.clientY - touch1.clientY;

    return Math.sqrt(dx * dx + dy * dy);
  }

  // function handleTouchStart(e: any) {
  //   if (e.touches.length === 2 && isZooming.value) {
  //     // 记录两个手指的初始位置
  //     const initialTouches = [e.touches[0], e.touches[1]];
  //     const initialDistance = getDistance(initialTouches[0], initialTouches[1]);

  //     console.log('开始拖动', initialDistance);
  //   }
  // }
  function handleTouchStart(e: any) {
    if (e.touches.length === 2 && isZooming.value) {
      // 更新全局变量
      initialTouches = [e.touches[0], e.touches[1]];
      initialDistance = getDistance(initialTouches[0], initialTouches[1]);
      console.log('开始拖动', initialDistance);
    }
  }

  // 触摸移动事件处理函数
  function handleTouchMove(e: any) {
    if (e.touches.length === 2 && isZooming.value) {
      const currentDistance = getDistance(e.touches[0], e.touches[1]);
      const scaleChange = currentDistance / initialDistance;

      // 更新图片缩放
      state.imgScale *= scaleChange;
      draw('');

      // 更新初始距离
      initialDistance = currentDistance;

      // 计算平移
      const deltaX =
        (e.touches[0].clientX + e.touches[1].clientX) / 2 -
        (initialTouches[0].clientX + initialTouches[1].clientX) / 2;
      const deltaY =
        (e.touches[0].clientY + e.touches[1].clientY) / 2 -
        (initialTouches[0].clientY + initialTouches[1].clientY) / 2;

      // 更新图片位置
      state.imgPosition = {
        x: state.imgPosition.x + deltaX,
        y: state.imgPosition.y + deltaY,
      };
      draw('');
    }
  }

  // 触摸结束事件处理函数
  function handleTouchEnd(e: any) {
    if (e.touches.length < 2) {
      initialDistance = 0;
      initialTouches = [];
      isZooming.value = false; // 重置放大状态
    }
  }

  // 双指检测完成
  onMounted(() => {
    loding.value = true;
    hbheight.value = box.value.offsetHeight;
    hbwidth.value = box.value.offsetWidth;
    state.canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
    state.ctx = state.canvas.getContext('2d', { willReadFrequently: true });
    state.img.crossOrigin = 'anonymous';
    // 处理图片id
    const imgsrcd = imgsrc.value.find(
      (item) => item.medicineAtlasImgId == dcomid.value
    );
    if (!imgsrcd) {
      state.img.src = base.value + imgsrc.value[0].imgUrl;
      dcomid.value = imgsrc.value[0].medicineAtlasImgId;
    } else {
      console.log('走了缓存');

      state.img.src = base.value + imgsrcd.imgUrl;
    }

    state.img.onload = () => {
      loadMarkers();

      state.imgWidth = state.img.width;
      state.imgHeight = state.img.height;
      // 查询标记点为
      getPointnew({
        medicineAtlasId: medicineAtlasId.value,
        pageNum: 1,
        pageSize: 800,
      }).then((res: any) => {
        if (res.code == 200) {
          state.markers = [];
          saveMarkers();
          // console.log('查询解刨点测试', res.data);
          const markersMap = new Map(
            state.markers.map((marker: any) => [
              marker.medicineAtlasImgId,
              marker,
            ])
          );

          for (const items of res.data) {
            try {
              if (items.medicineAtlasImgId != null) {
                const existingMarker = markersMap.get(items.medicineAtlasImgId);
                const markingPointsObjects = JSON.parse(items.markingPoints);
                markingPointsObjects.medicineAtlasImgId =
                  items.medicineAtlasImgId;

                markingPointsObjects.bsdata[0].markingPointsId =
                  items.markingPointsId;
                markingPointsObjects.bsdata[0].flag = true;
                markingPointsObjects.bsdata[0].labels = true;
                markingPointsObjects.bsdata[0].anatomicStructureName =
                  items.anatomicStructureName;
                markingPointsObjects.bsdata[0].anatomicStructureId =
                  items.anatomicStructureId;

                if (existingMarker) {
                  existingMarker.bsdata.push(...markingPointsObjects.bsdata);
                } else {
                  markersMap.set(
                    items.medicineAtlasImgId,
                    markingPointsObjects
                  );
                }
              }
            } catch (error) {
              console.error('Error processing item:', items, error);
            }
          }

          // 更新 state.markers
          state.markers = Array.from(markersMap.values());

          // 确保数据不为空
          if (state.markers.length === 0) {
            console.error('Final markers array is empty. Check input data.');
          } else {
            // console.log('Final markers:', state.markers);
          }

          // console.log('打印获取的点位数据', state.markers);

          draw('');
        }
      });
    };
    state.img.onerror = (error) => {
      console.error('Failed to load image:', error);
    };
    state.canvas.addEventListener('mousedown', startDrag);
    state.canvas.addEventListener('mousemove', handleMouseMove);
    state.canvas.addEventListener('mouseup', stopDrag);
    state.canvas.addEventListener('touchmove', handleMouseMove);
    state.canvas.addEventListener('touchend', stopDrag);
    state.canvas.addEventListener('click', handleCanvasClick);
    state.canvas.addEventListener('wheel', handleWheel);
    state.canvas.addEventListener('touchstart', startDrag);
    state.canvas!.addEventListener('touchstart', handleCanvasClick, {
      passive: false,
    });

    // 添加单只滑动图片事件
    state.canvas.addEventListener('touchstart', touchStartHandler);
    state.canvas.addEventListener('touchmove', touchMoveHandler);
    state.canvas.addEventListener('touchend', touchEndHandler);
    state.canvas.addEventListener('touchcancel', touchEndHandler); // 取消触摸时也重置滑动状态

    // 添加双指事件
    state.canvas.addEventListener('touchstart', handleTouchStart, false);
    state.canvas.addEventListener('touchmove', handleTouchMove, false);
    state.canvas.addEventListener('touchend', handleTouchEnd, false);
    // 监听窗口大小变化
    window.addEventListener('resize', handleResize);

    document.addEventListener('keydown', handleKeyDown);
    document.addEventListener('keyup', handleKeyUp);
    // 阻止双击放大
    document.addEventListener(
      'dblclick',
      function (e) {
        e.preventDefault();
      },
      { passive: false }
    );

    // 获取一下解刨结构数据
    jpList({
      medicineAtlasId: medicineAtlasId.value,
      pageNum: 1,
      pageSize: 999,
    }).then((res: any) => {
      if (res.code == 200) {
        optionsdata.value = res.data.list.map((item: any) => {
          return { ...item, flag: true }; // 为每个对象添加 flag 属性
        });

        // console.log('查询解刨数据成功', optionsdata.value);
        // 给结构添加属性来绑定
      }
    });
  });

  onBeforeUnmount(() => {
    if (state.canvas) {
      state.canvas.removeEventListener('mousedown', startDrag);
      state.canvas.removeEventListener('mousemove', handleMouseMove);
      state.canvas.removeEventListener('mouseup', stopDrag);
      state.canvas.removeEventListener('click', handleCanvasClick);
      state.canvas.removeEventListener('wheel', handleWheel);

      // state.canvas.removeEventListener('resize', handleResize);
      // 新增的一处

      state.canvas.removeEventListener('touchstart', handleTouchStart, false);
      state.canvas.removeEventListener('touchmove', handleTouchMove, false);
      state.canvas.removeEventListener('touchend', handleTouchEnd, false);
    }
    window.removeEventListener('resize', handleResize);
    document.removeEventListener('keydown', handleKeyDown);
    document.removeEventListener('keyup', handleKeyUp);
  });
  const reset = () => {
    // 重置状态
    state.imgScale = 0.4;

    state.zoomStep = 0.1;
    state.rotation = 0;
    state.flipHorizontal = false;
    state.flipVertical = false;
    state.imgOffsetX = 0;
    state.imgOffsetY = 0;
    state.currentText = '';
    state.currentMarker = null;
    state.addflag = false;
    state.showLinesAndText = true;

    // 重新加载并绘制图像
    const imgsrcd = imgsrc.value.find(
      (item) => item.medicineAtlasImgId == dcomid.value
    );

    state.img.src = base.value + imgsrcd!.imgUrl;
    state.img.onload = () => {
      loadMarkers();
      draw('');
    };
  };
  const changecsd = () => {
    if (allflag.value == true) {
      // console.log('当前是否全选', allflag.value, state.markers);
      state.markers.forEach((item) => {
        item.bsdata.forEach((items: any) => {
          items.flag = true;
        });
      });
      // JGkgdata.value.forEach((isd) => {
      //   isd = true;
      //   console.log('sss', isd);
      // });

      saveMarkers();
      draw('');
    }
    if (allflag.value == false) {
      state.markers.forEach((item) => {
        item.bsdata.forEach((items: any) => {
          items.flag = false;
        });
      });

      saveMarkers();
      draw('');
    }
  };
  const changecs = (i: any) => {
    // console.log('关联解剖结构测试', i);
    state.markers.some((item: any) => {
      const itemsArray = item.medicineAtlasImgId.split(',').map(Number);
      if (itemsArray.includes(dcomid.value)) {
        item.bsdata.some((itemd: any) => {
          if (itemd.anatomicStructureId == i.anatomicStructureId) {
            itemd.flag = i.flag;
          }
        });
      }
    });
    draw('');
  };

  const JGkgdata = ref([]);
  const allflag = ref(true);
  const classificationName = ref('全部');
  const imggroupname = ref('全部');
  const fieldNames = ref({
    value: 'classificationName',
    label: 'classificationName',
  });
  const fieldNamess = ref({
    value: 'typeName',
    label: 'typeName',
  });

  // 扫描面

  // 图像解刨面更改
  const changeimgclassfn = (i: any) => {
    console.log('点击了', i);
    classificationName.value = i;
    // classificationName.value = i.classificationName;
    imgsrc.value = [];
    imgsrcs.value.forEach((item: any) => {
      if (classificationName.value == item.imgClassificationName) {
        imgsrc.value.push(item);
      }
    });
    if (i == '全部') {
      imgsrc.value = imgsrcs.value;
    }
    //
    dcomid.value = imgsrc.value[0].medicineAtlasImgId;
    tagdcom(dcomid.value, '');
  };
  // 图像分组更改
  const changeimggroupfn = (i: any) => {
    if (i == '全部') {
      imggroupname.value = '全部';
      imgsrc.value = imgsrcs.value;
      dcomid.value = imgsrc.value[0].medicineAtlasImgId;
      tagdcom(dcomid.value, '');
      return;
    }
    imggroupname.value = i.typeName;
    const item = imggroup.value.find(
      (img: any) => img.typeName == imggroupname.value
    );
    // 处理图像classificationName.value.includes(img.imgClassificationName)
    // console.log('检测到图像分组更改', item);
    const imgsrcsd = item as any;
    const imgsrcmw = imgsrc.value;
    imgsrc.value = [];
    console.log('切换图像debug', imgsrcsd);
    //  加一层判断吧
    if (classificationName.value != '') {
      imgsrcsd.typeImg.forEach((itemd: any) => {
        if (classificationName.value == itemd.imgClassificationName) {
          imgsrc.value.push(itemd);
          console.log('切换图像debug3', imgsrc.value, imgsrc.value.length);
        }
      });
    } else {
      imgsrc.value = imgsrcsd.typeImg;
      console.log('切换图像debug2', imgsrc.value, imgsrc.value.length);
    }

    if (imgsrc.value.length > 0) {
      dcomid.value = imgsrc.value[0].medicineAtlasImgId;
      tagdcom(dcomid.value, '');
    } else {
      // console.log('当前图像没有T2');
      imgsrc.value = imgsrcmw;
      Message.warning({
        content: '暂无图像!',
      });
    }
    // imgsrc.value = item.typeImg;
  };
  const flag = ref(false);
  const flagfn = (i: any) => {
    // console.log('当前id是否存在本图中', i.anatomicStructureId);
    return state.markers.some((item: any) => {
      const itemsArray = item.medicineAtlasImgId.split(',').map(Number);
      if (itemsArray.includes(dcomid.value)) {
        return item.bsdata.some(
          (itemd: any) => itemd.anatomicStructureId === i.anatomicStructureId
        );
      }
      return false;
    });
  };

  // 定义画布高度
  const hbheight = ref();
  const hbwidth = ref();
  // 定义画布

  // 定义左右两侧数据
  const leftMarkers = ref<any[]>([]);
  const rightMarkers = ref<any[]>([]);
  const textModeEnabled = ref(false); // 控制是否启用添加文字模式
  const jubushow = ref(false);

  // 局部标签适配
  const jubu = () => {
    console.log('jubushow', jubushow.value);

    const matchingItems = state.markers.filter((item: any) =>
      item.medicineAtlasImgId.includes(dcomid.value)
    );

    matchingItems.forEach((item) => {
      item.bsdata.forEach((items: any) => {
        items.labels = false; // 切换标签状态
      });
    });

    saveMarkers();
    draw('');

    const canvasContainer = document.getElementById('canvasContainer');
    if (!canvasContainer) return; // 确保容器存在

    // 确保父容器是相对定位
    canvasContainer.style.position = 'relative';

    // 检查是否已有子画布，若存在则移除并退出
    const existingOverlayCanvas = canvasContainer.querySelector(
      'canvas[data-role="overlay"]'
    );
    if (existingOverlayCanvas) {
      canvasContainer.removeChild(existingOverlayCanvas);
      canvasContainer
        .querySelectorAll('div[data-role="resize-handle"]')
        .forEach((circle) => circle.remove());
      return; // 不再执行后续代码
    }

    // 创建并设置新的子 canvas
    const overlayCanvas = document.createElement('canvas');
    overlayCanvas.width = 80;
    overlayCanvas.height = 80;
    overlayCanvas.style.cssText = `
                border: 1px solid #ffffff;
                position: absolute;
                z-index: 10;
                left:150px; /* 初始位置 */
                top: 150px; /* 初始位置 */
                cursor: move;
            `;
    overlayCanvas.setAttribute('data-role', 'overlay'); // 添加标识以便后续查找
    canvasContainer.appendChild(overlayCanvas);

    // 当前画布状态
    let currentState = {
      width: overlayCanvas.width,
      height: overlayCanvas.height,
      left: parseFloat(overlayCanvas.style.left),
      top: parseFloat(overlayCanvas.style.top),
    };

    // 是否在拖动模式
    let isDragging = false;
    let dragOffsetX = 0;
    let dragOffsetY = 0;

    // 判断是否为触摸设备
    const isTouchDevice =
      'ontouchstart' in window || navigator.maxTouchPoints > 0;

    // 画布拖动逻辑
    const startDragx = (e: any) => {
      e.preventDefault();
      isDragging = true;
      const clientX = isTouchDevice ? e.touches[0].clientX : e.clientX;
      const clientY = isTouchDevice ? e.touches[0].clientY : e.clientY;
      dragOffsetX = clientX - overlayCanvas.offsetLeft;
      dragOffsetY = clientY - overlayCanvas.offsetTop;

      const onMove = (moveEvent: any) => {
        if (!isDragging) return;
        const newX =
          (isTouchDevice ? moveEvent.touches[0].clientX : moveEvent.clientX) -
          dragOffsetX;
        const newY =
          (isTouchDevice ? moveEvent.touches[0].clientY : moveEvent.clientY) -
          dragOffsetY;
        currentState.left = newX;
        currentState.top = newY;

        overlayCanvas.style.left = `${newX}px`;
        overlayCanvas.style.top = `${newY}px`;

        updateControlPoints();
        updateMarkers(); // 更新标记点状态
      };

      const stopDragx = () => {
        isDragging = false;
        window.removeEventListener(
          isTouchDevice ? 'touchmove' : 'mousemove',
          onMove
        );
        window.removeEventListener(
          isTouchDevice ? 'touchend' : 'mouseup',
          stopDragx
        );
        draw(''); // 拖动完成后更新画布
      };

      window.addEventListener(
        isTouchDevice ? 'touchmove' : 'mousemove',
        onMove
      );
      window.addEventListener(
        isTouchDevice ? 'touchend' : 'mouseup',
        stopDragx
      );
    };

    overlayCanvas.addEventListener(
      isTouchDevice ? 'touchstart' : 'mousedown',
      startDragx
    );

    // 更新圆点位置
    const updateControlPoints = () => {
      const canvasRect = overlayCanvas.getBoundingClientRect();
      const containerRect = canvasContainer.getBoundingClientRect();

      const controlPoints = [
        {
          x: canvasRect.left - containerRect.left,
          y: canvasRect.top - containerRect.top,
        }, // 左上角
        {
          x: canvasRect.left - containerRect.left + canvasRect.width / 2,
          y: canvasRect.top - containerRect.top,
        }, // 顶边中心
        {
          x: canvasRect.right - containerRect.left,
          y: canvasRect.top - containerRect.top,
        }, // 右上角
        {
          x: canvasRect.left - containerRect.left,
          y: canvasRect.top - containerRect.top + canvasRect.height / 2,
        }, // 左边中心
        {
          x: canvasRect.right - containerRect.left,
          y: canvasRect.top - containerRect.top + canvasRect.height / 2,
        }, // 右边中心
        {
          x: canvasRect.left - containerRect.left,
          y: canvasRect.bottom - containerRect.top,
        }, // 左下角
        {
          x: canvasRect.left - containerRect.left + canvasRect.width / 2,
          y: canvasRect.bottom - containerRect.top,
        }, // 底边中心
        {
          x: canvasRect.right - containerRect.left,
          y: canvasRect.bottom - containerRect.top,
        }, // 右下角
      ];

      controlHandles.forEach((circle: any, index: any) => {
        circle.style.left = `${controlPoints[index].x - 5}px`;
        circle.style.top = `${controlPoints[index].y - 5}px`;
      });
    };

    // 更新标记点状态
    const updateMarkers = () => {
      const scaledWidth = state.img.naturalWidth * state.imgScale;
      const scaledHeight = state.img.naturalHeight * state.imgScale;

      const canvasOffsetX =
        (state.canvas.width - scaledWidth) / 2 + state.imgOffsetX;
      const canvasOffsetY =
        (state.canvas.height - scaledHeight) / 2 + state.imgOffsetY;

      const localCanvasLeft = currentState.left - canvasOffsetX;
      const localCanvasTop = currentState.top - canvasOffsetY;
      const localCanvasRight = localCanvasLeft + currentState.width;
      const localCanvasBottom = localCanvasTop + currentState.height;

      matchingItems.forEach((item) => {
        item.bsdata.forEach((marker: any) => {
          const scaledMarkerX = marker.x * state.imgScale;
          const scaledMarkerY = marker.y * state.imgScale;

          const isInside =
            scaledMarkerX >= localCanvasLeft &&
            scaledMarkerX <= localCanvasRight &&
            scaledMarkerY >= localCanvasTop &&
            scaledMarkerY <= localCanvasBottom;

          marker.labels = isInside; // 根据是否在区域内更新状态
        });
      });
    };

    // 添加圆点
    const controlHandles: any = [];
    const createCircle = (index: any) => {
      const circle = document.createElement('div');
      circle.style.cssText = `
                    width: 10px;
                    height: 10px;
                    background-color: #ff0000;
                    border-radius: 50%;
                    position: absolute;
                    z-index: 15;
                    cursor: pointer;
                `;
      circle.setAttribute('data-index', index);
      circle.setAttribute('data-role', 'resize-handle');
      canvasContainer.appendChild(circle);
      return circle;
    };

    for (let i = 0; i < 8; i++) {
      const circle = createCircle(i);
      controlHandles.push(circle);
      let isResizing = false;

      circle.addEventListener(
        isTouchDevice ? 'touchstart' : 'mousedown',
        (e: any) => {
          e.preventDefault();
          e.stopPropagation(); // 防止触发拖动事件
          isResizing = true;

          const startX = isTouchDevice ? e.touches[0].clientX : e.clientX;
          const startY = isTouchDevice ? e.touches[0].clientY : e.clientY;

          const startState = { ...currentState };

          const onResizeMove = (moveEvent: any) => {
            if (!isResizing) return;

            const dx =
              (isTouchDevice
                ? moveEvent.touches[0].clientX
                : moveEvent.clientX) - startX;
            const dy =
              (isTouchDevice
                ? moveEvent.touches[0].clientY
                : moveEvent.clientY) - startY;

            switch (i) {
              case 0: // 左上角
                currentState.width = startState.width - dx;
                currentState.height = startState.height - dy;
                currentState.left = startState.left + dx;
                currentState.top = startState.top + dy;
                break;
              case 1: // 顶边中心
                currentState.height = startState.height - dy;
                currentState.top = startState.top + dy;
                break;
              case 2: // 右上角
                currentState.width = startState.width + dx;
                currentState.height = startState.height - dy;
                currentState.top = startState.top + dy;
                break;
              case 3: // 左边中心
                currentState.width = startState.width - dx;
                currentState.left = startState.left + dx;
                break;
              case 4: // 右边中心
                currentState.width = startState.width + dx;
                break;
              case 5: // 左下角
                currentState.width = startState.width - dx;
                currentState.height = startState.height + dy;
                currentState.left = startState.left + dx;
                break;
              case 6: // 底边中心
                currentState.height = startState.height + dy;
                break;
              case 7: // 右下角
                currentState.width = startState.width + dx;
                currentState.height = startState.height + dy;
                break;
            }

            overlayCanvas.style.width = `${currentState.width}px`;
            overlayCanvas.style.height = `${currentState.height}px`;
            overlayCanvas.style.left = `${currentState.left}px`;
            overlayCanvas.style.top = `${currentState.top}px`;

            updateControlPoints();
            updateMarkers();
          };

          const stopResize = () => {
            isResizing = false;
            window.removeEventListener(
              isTouchDevice ? 'touchmove' : 'mousemove',
              onResizeMove
            );
            window.removeEventListener(
              isTouchDevice ? 'touchend' : 'mouseup',
              stopResize
            );
            draw(''); // 调整完成后更新画布
          };

          window.addEventListener(
            isTouchDevice ? 'touchmove' : 'mousemove',
            onResizeMove
          );
          window.addEventListener(
            isTouchDevice ? 'touchend' : 'mouseup',
            stopResize
          );
        }
      );
    }

    updateControlPoints(); // 初始化控制点位置
    updateMarkers(); // 初始化标记点状态
  };

  // 局部标签完成
  // 添加画布 生成画板操作
  const pzshow = ref(false);

  const context = ref<CanvasRenderingContext2D | null>(null);
  const overlayContext = ref<CanvasRenderingContext2D | null>(null); // 声明类型
  const isDrawing = ref(false);
  const isCanvasVisible = ref(false); // 用于控制画布是否可见
  const customText = ref(''); // 用于存储自定义输入的文字
  const showInput = ref(false); // 控制输入框是否显示
  const inputStyle = ref<CSSProperties>({
    left: '',
    top: '',
    position: 'absolute', // 'absolute' 是一个有效的 position 类型
  }); // 输入框的位置样式
  const isInputActive = ref(false); // 控制输入框是否激活
  const currentMode = ref('drawing'); // 初始为绘制模式
  const currentCursorStyle = ref('crosshair'); // 默认光标为十字架
  const myStyle = ref('inherit');
  const pzfn = () => {
    mentshow.value = false;
    // 动态显示画布并获取上下文
    isCanvasVisible.value = pzshow.value;

    nextTick(() => {
      const myCanvas = document.getElementById('myCanvas') as HTMLCanvasElement;
      const overlayCanvas = document.getElementById(
        'overlayCanvas'
      ) as HTMLCanvasElement;

      // 获取画布上下文
      context.value = myCanvas.getContext('2d', {
        willReadFrequently: true,
      }) as CanvasRenderingContext2D;
      overlayContext.value = overlayCanvas.getContext('2d', {
        willReadFrequently: true,
      }) as CanvasRenderingContext2D;

      // 保存初始状态（确保正确的画布）
      canvasHistory.value.push(
        overlayContext.value.getImageData(
          0,
          0,
          overlayCanvas.width,
          overlayCanvas.height
        )
      );

      console.log('初始状态已保存:', canvasHistory.value);
    });
  };

  const startDrawing = (event: any) => {
    if (currentMode.value != 'drawing') {
      return;
    }
    isDrawing.value = true;
    draws(event); // 开始绘制
  };

  const stopDrawing = () => {
    isDrawing.value = false;
    overlayContext.value!.beginPath();

    const MAX_HISTORY = 20; // 最大历史记录长度

    const addHistoryState = () => {
      const canvas = document.getElementById(
        'overlayCanvas'
      ) as HTMLCanvasElement;
      const currentState = overlayContext.value!.getImageData(
        0,
        0,
        canvas.width,
        canvas.height
      );

      // 如果超出最大长度，移除最早的记录
      if (canvasHistory.value.length >= MAX_HISTORY) {
        canvasHistory.value.shift();
      }
      canvasHistory.value.push(currentState);

      console.log('添加历史记录，当前记录数:', canvasHistory.value.length);
    };
    // 保存当前状态到历史记录
    addHistoryState();
  };

  const brushColor = ref('#ff0000'); // 默认画笔颜色
  const brushSize = ref(1); // 默认画笔粗细
  const canvasHistory = ref<any[]>([]); // 保存画布状态的栈
  const isEraserMode = ref(false); // 标识是否为橡皮擦模式

  const brushColorfn = (item) => {
    (brushColor.value = item), (tsshow.value = false);
  };
  // 绘制标记主函数
  const draws = (event: any) => {
    event.preventDefault();
    if (!isDrawing.value || !overlayContext.value) return;

    const rect = document
      .getElementById('overlayCanvas')
      ?.getBoundingClientRect();

    let x, y;

    // 判断是否是触摸事件
    if (event.touches && event.touches.length > 0) {
      x = event.touches[0].clientX - rect!.left;
      y = event.touches[0].clientY - rect!.top;
    } else {
      x = event.clientX - rect!.left;
      y = event.clientY - rect!.top;
    }

    if (isEraserMode.value) {
      // 如果是橡皮擦模式，擦除线段
      erase(x, y);
    } else {
      // 否则是绘制模式
      overlayContext.value.lineWidth = Number(brushSize.value); // 使用动态线宽
      overlayContext.value.lineCap = 'round';
      overlayContext.value.strokeStyle = brushColor.value; // 使用动态颜色

      overlayContext.value.lineTo(x, y);
      overlayContext.value.stroke();
      overlayContext.value.beginPath();
      overlayContext.value.moveTo(x, y);
    }
  };

  // 切换橡皮擦模式
  const toggleEraser = () => {
    isEraserMode.value = !isEraserMode.value;
    console.log(isEraserMode.value ? '橡皮擦模式启用' : '橡皮擦模式禁用');
  };

  // 橡皮擦擦除函数
  const erase = (x: number, y: number, tolerance: number = 10) => {
    const canvas = document.getElementById(
      'overlayCanvas'
    ) as HTMLCanvasElement;

    // 获取画布数据
    const imageData = overlayContext.value.getImageData(
      0,
      0,
      canvas.width,
      canvas.height
    );
    const data = imageData.data;

    // 获取擦除区域的像素数据
    const eraseRadius = brushSize.value + tolerance; // 扩大半径以确保擦除范围足够

    // 循环遍历每个像素
    for (let i = 0; i < data.length; i += 4) {
      const px = (i / 4) % canvas.width;
      const py = Math.floor(i / 4 / canvas.width);
      const dx = px - x;
      const dy = py - y;

      // 计算当前像素点到鼠标点的距离
      if (Math.sqrt(dx * dx + dy * dy) < eraseRadius) {
        data[i] = 255; // R
        data[i + 1] = 255; // G
        data[i + 2] = 255; // B
        data[i + 3] = 0; // A (透明度)
      }
    }

    // 更新画布
    overlayContext.value.putImageData(imageData, 0, 0);
  };

  // 撤销
  const redrawCanvas = () => {
    const canvas = document.getElementById(
      'overlayCanvas'
    ) as HTMLCanvasElement | null;
    if (canvas) {
      overlayContext.value!.clearRect(0, 0, canvas.width, canvas.height); // 清空画布
    }

    if (canvasHistory.value.length > 0) {
      // 恢复最后的画布状态
      const lastState = canvasHistory.value[canvasHistory.value.length - 1];
      overlayContext.value!.putImageData(lastState, 0, 0);
    }
  };

  // 撤销方法
  const undo = () => {
    console.log('历史记录是否有', canvasHistory.value);

    if (canvasHistory.value.length > 0) {
      console.log('执行了撤销');
      // 保存当前状态到还原栈
      // 保存当前状态到还原栈
      redoHistory.value.push(
        canvasHistory.value[canvasHistory.value.length - 1]
      );
      // const canvasHistoryd = canvasHistory.value;
      // redoHistory.value = canvasHistoryd;
      console.log('当前数据站', redoHistory.value);

      // 弹出最近的状态
      canvasHistory.value.pop();

      // 重绘画布
      nextTick(() => {
        redrawCanvas();
      });
    } else {
      clearOverlay();
      console.log('没有可以撤销的历史记录');
    }
  };
  const redoHistory = ref([]); // 保存还原的历史记录
  // 还原方法
  const redo = () => {
    console.log('还原历史记录是否有', redoHistory.value);

    if (redoHistory.value.length > 0) {
      console.log('执行了还原');
      // 获取最近的还原状态
      const lastUndoState = redoHistory.value.pop();

      // 将其恢复到撤销栈
      canvasHistory.value.push(lastUndoState);

      // 重绘画布
      nextTick(() => {
        redrawCanvas();
      });
    } else {
      console.log('没有可以还原的历史记录');
    }
  };
  const showTextInput = (event: any) => {
    if (currentMode.value != 'text') {
      return;
    }

    const rect = document
      .getElementById('overlayCanvas')
      ?.getBoundingClientRect();
    const x = event.clientX - rect!.left;
    const y = event.clientY - rect!.top;

    // 设置输入框的位置
    inputStyle.value = {
      position: 'absolute',
      left: `${event.clientX - 10}px`, // 可以考虑做一些微调
      top: `${event.clientY - 65}px`, // 根据需要微调
      // 使输入框的光标对齐到点击位置
    };
    customText.value = ''; // 清空输入框内容
    showInput.value = true; // 显示输入框

    // 使用 nextTick 确保输入框显示后立即获得焦点
    nextTick(() => {
      const inputElement = document.querySelector(
        '.text-input'
      ) as HTMLInputElement | null;
      if (inputElement) {
        inputElement.focus(); // 设置焦点
      }
    });
  };

  const addTextMarker = (text: any, x: any, y: any) => {
    if (!overlayContext.value) {
      console.error('Overlay context is not initialized');
      return; // 如果 overlayContext 未初始化，直接返回
    }

    overlayContext.value.font = '20px Arial'; // 设置字体和大小
    overlayContext.value.fillStyle = 'blue'; // 设置文字颜色
    overlayContext.value.fillText(text, x, y); // 添加文字标记
  };

  // 处理输入框失去焦点事件
  const addTextMarkerOnBlur = () => {
    if (customText.value) {
      addTextMarker(
        customText.value,
        parseFloat(inputStyle.value.left as string),
        parseFloat(inputStyle.value.top as string)
      ); // 获取输入框位置
    }
    showInput.value = false; // 隐藏输入框
  };

  // 处理回车事件
  const addTextMarkerOnEnter = (event: any) => {
    if (event.key === 'Enter' && customText.value) {
      addTextMarker(
        customText.value,
        parseFloat(inputStyle.value.left as string),
        parseFloat(inputStyle.value.top as string)
      ); // 获取输入框位置
      showInput.value = false; // 隐藏输入框
    }
  };

  // 处理输入框失去焦点事件
  const handleInputBlur = () => {
    isInputActive.value = false; // 重置输入框激活状态
    addTextMarkerOnBlur();
  };

  // 切换到文字输入模式
  const enableTextMode = () => {
    nextTick(() => {
      currentMode.value = 'text';
      currentCursorStyle.value = 'text';
    });
    // 设置为文本光标
  };

  // 切换到绘制模式
  const enableDrawingMode = () => {
    isEraserMode.value = false;
    nextTick(() => {
      currentMode.value = 'drawing';
      currentCursorStyle.value = 'crosshair'; // 设置为十字架光标
    });
  };

  // 切换到保存图片下载模式
  const downloadImage = () => {
    currentMode.value = 'download';
    const myCanvas = document.getElementById('myCanvas') as HTMLCanvasElement;
    const overlayCanvas = document.getElementById(
      'overlayCanvas'
    ) as HTMLCanvasElement;

    const combinedCanvas = document.createElement('canvas');
    combinedCanvas.width = hbwidth.value;
    combinedCanvas.height = hbheight.value;
    const ctx = combinedCanvas.getContext('2d', {
      willReadFrequently: true,
    }) as CanvasRenderingContext2D;
    // 设置背景颜色为黑色
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, combinedCanvas.width, combinedCanvas.height);
    // 绘制原始画布的内容
    ctx.drawImage(myCanvas, 0, 0);

    // 绘制标记画布的内容
    ctx.drawImage(overlayCanvas, 0, 0);
    console.log('报错的拖', combinedCanvas);

    try {
      // 将合成的画布转换为数据URL
      const imageDataURL = combinedCanvas.toDataURL('image/png');

      // 创建下载链接并触发下载
      const link = document.createElement('a');
      link.href = imageDataURL;
      link.download = 'combined_image.png'; // 下载文件名
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } catch (error) {
      console.error('Error exporting canvas: ', error);
    }
  };

  // 清除模式
  const clearOverlay = () => {
    currentMode.value = 'delel';
    const overlayCanvas = document.getElementById(
      'overlayCanvas'
    ) as HTMLCanvasElement;
    if (overlayCanvas) {
      const overlayContext = overlayCanvas.getContext('2d', {
        willReadFrequently: true,
      }) as CanvasRenderingContext2D;
      overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // 清空画布
    } else {
      console.error('Overlay canvas not found');
    }
  };

  // 处理窗口大小变化的函数
  const handleResize = () => {
    console.log('窗口发生变化是否充值');

    if (state.canvas && !isCanvasVisible.value) {
      // 更新画布的宽高

      hbheight.value = box.value.offsetHeight;
      hbwidth.value = box.value.offsetWidth;

      // 更新画布大小
      // 重新绘制画布内容（如果需要）
      state.canvas.width = hbwidth.value;
      state.canvas.height = hbheight.value;
      // state.imgWidth = state.img.width;
      // state.imgHeight = state.img.height;
      // 更新绘制
      tagdcom(dcomid.value, '');
    }
  };

  // 调色板预制参数
  const brushColordata = ref([
    '#d9001b',
    '#F59A23',
    '#FFFF00',
    '#95F204',
    '#00FFFF',
    '#02A7F0',
    '#0000FF',
    '#8400FF',
    '#FFFFFF',
    '#000000',
  ]);
  const tsshow = ref(false);

  // 粗细版本预制
  const hbcshow = ref(false);
  const brushSizedata = ref([1, 2, 3, 4, 5, 6, 7]);
  // 关闭搜索
  const mainpoint = ref(false);
  const backfn = () => {
    mainpoint.value = false;
  };
</script>

<style scoped>
  .backfn {
    font-size: 36px;
  }
  .mainpoint {
    height: 100%;
    width: 100%;
    background-color: #fff;
  }
  .mainpointbox {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 10px 20px;
    font-size: 36px;
  }
  .mainpointitem {
    background-color: #eef1f4;
    border-radius: 20px;
    padding: 10px 15px;
    width: 650px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-items: center;
    margin: 10px 0;
    font-size: 26px;
  }
  .mainpointtop {
    width: 100%;
    height: 170px;
    background: linear-gradient(180deg, #8f9cab 0%, #ffffff 81%);
  }
  .overlayCanvastooitems {
    background: #409eff;
  }
  .text-input-container {
    /* 输入框的容器样式 */
    z-index: 99;
  }
  .text-input-container input {
    width: 200px;
  }

  .text-input {
    padding: 5px;
    border: 1px solid #ccc;
  }
  #overlayCanvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2; /* 画板层 */
  }
  .bjbox {
    width: 100%;
    height: 172px;
  }
  .bjbox img {
    width: 100%;
    height: 172px;
  }
  .mainboxgj {
    display: flex;
    width: 100%;
    height: 100%;
  }
  .mainlefttopbox {
    width: 100%;
    height: 10%;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    position: relative;
  }
  .mainsera {
    position: absolute;
    left: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .mainsers {
    width: 200px;
    position: absolute;
    right: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .maintoptitle {
    font-weight: bold;
    font-size: 20px;
    color: #ffffff;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 54px;
  }
  .maintopright {
    display: flex;
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translate(0, -50%);
  }
  .czmainitem {
    cursor: pointer;
    margin: 0 5px;
  }

  .gnbottom {
    background-color: #28292b;
    width: 100%;
    height: 8%;
    /* height: 65px; */
    padding: 0px 18px;
    z-index: 9;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .gnbottom img {
    width: 40px;
    height: 40px;
  }

  #canvasContainer {
    position: relative;
  }
  #myCanvas {
    /* border: solid 1px #00ff80; */
    background-color: black;
  }
  .mentox {
    height: 50px;
    border-radius: 6px 6px 6px 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 500;
    color: #ffffff;

    font-size: 28px;
  }
  .mentox span {
    display: block;

    font-size: 28px;
    margin-left: 10px;
    word-spacing: 20px;
  }
  .boxs {
    width: 300px;
    display: flex;
    flex-direction: column;
    align-content: center;
    justify-content: center;
  }
  .zsdkz {
    font-size: 26px !important;
    color: #000000;
    line-height: 30px;
    padding: 5px 10px;
    height: 400px;
    /* height: 230px; */
    overflow-y: auto;
  }
  .boxsitem {
    width: 130px;
    height: 130px;
    margin: 10px 25px;
    background: black;
  }
  .boxsitems {
    text-align: center;
  }
  .box {
    margin: 0 auto;
    background-color: rgb(223, 60, 60);
    width: 100%;
    height: 70%;
    position: relative;
    z-index: 9;
  }

  .mainboxleft {
    width: 100%;
    height: 100%;
  }
  .lbox {
    background-color: #28292b;
    width: 100%;
    height: 12%;
    /* height: 110px; */
    display: flex;
    overflow: hidden;
    overflow-x: auto;
    white-space: nowrap;
    position: absolute;
    /* bottom: 1px; */

    /* border-top: 2px solid #5a5a5a; */
  }

  .lboxitem {
    background-color: black;
    width: 75px;

    height: 100px;
    margin: 0px 3px;
    cursor: pointer;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .lboxitem img {
    width: 75px;
    height: 100px;
  }

  .msx {
    width: 75px;
    height: 96px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 1px solid #fff;
  }

  .lbox::-webkit-scrollbar {
    width: 5px;
    height: 5px;
  }

  .lbox::-webkit-scrollbar-track {
    width: 6px;
    background: rgba(#101f1c, 0.1);
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
  }

  .lbox::-webkit-scrollbar-thumb {
    background-color: rgba(133, 138, 148, 0.938);
    background-clip: padding-box;
    min-height: 28px;
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
    transition: background-color 0.3s;
    cursor: pointer;
  }

  .lbox::-webkit-scrollbar-thumb:hover {
    background-color: rgba(144, 147, 153, 0.3);
  }

  .xbanner {
    width: 100%;
    font-size: 16px;
    height: 40px;
    background-color: #fff;
    /* line-height: 40px; */
    padding-left: 10px;
    align-content: center;
  }
  .xbannername {
    cursor: pointer;
    display: flex;
    align-items: center;
    font-size: 16px;
  }
  /* 公共类 */
  /* 封装公共按钮类 */
  .tool {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .tool img.active {
    cursor: pointer;
    display: none;
  }

  .tool:hover img.normal,
  .tool.active img.normal {
    display: none;
  }

  .tool:hover img.active,
  .tool.active img.active {
    display: block;
  }

  .zsbox {
    width: 750px;
    /* height: 535px; */
    background: #ffffff;
    display: flex;
    flex-direction: column;

    border-top-left-radius: 30px;
    border-top-right-radius: 30px;

    align-items: center;
  }
  .zsboxname {
    width: 90%;
    font-size: 30px;
    border-bottom: 1px dashed #d2d0d0;
    margin-top: 50px;
  }
  .zsboxnamee {
    margin-top: 0px;
    margin: 15px 0;
    border-bottom: 2px dashed #e8e7e7;
  }
  .zsboxnameee {
    border-bottom: 0px dashed #e8e7e7;
  }
  .zsboxnames {
    font-size: 26px;
    color: #666;
    margin: 15px 0;
  }
  .zsboxclose {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 40px;
    height: 40px;
  }
  .zstop {
    height: 54px;
    width: 100%;
    font-size: 16px;
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /* .arco-drawer-header {
    background-color: black !important;
  }
  .chouti .arco-drawer {
    background-color: black !important;
  } */
  .zsclose {
    position: absolute;
    right: 20px;
    cursor: pointer;
  }
  .xbannername {
    cursor: pointer;
    display: flex;
    align-items: center;
    color: #fff;
  }

  .overlayCanvastool {
    position: fixed;
    top: 0px;
    z-index: 999;
    width: 100%;
    height: 90px;
    display: flex;
    align-items: center;

    background-color: black;
  }
  .overlayCanvastooitemd {
    width: 220px !important;
    text-align: left;
    color: #fff;
    font-size: 30px;
    padding-left: 15px;
  }
  .overlayCanvastooitem img {
    width: 53px;
    height: 53px;
  }
  .overlayCanvastooitem {
    color: #fff;
    font-size: 30px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0px 5px;
  }
  .startbox {
    width: 90px;
    height: 37px;
    background: linear-gradient(180deg, #f4f4f4 0%, #a2a2a2 100%);
    border-radius: 4px 4px 4px 4px;
    border: 1px solid #000000;
    font-weight: bold;
    font-size: 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 5px;
  }
  .startboxs {
    width: 90px;
    font-size: 16px;
    color: #fff;
  }
  .mentsimg {
    width: 40px;
    height: 40px;
  }

  .mentsshow {
    margin-right: 10px;
  }

  .ctfiexd {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    background: rgba(0, 0, 0, 0.75);
    z-index: 9;
  }
  .ctmain {
    width: 445px;
    background-color: #f3f5f7;
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 0px;
    right: 0px;
  }
  .cttopbox {
    background-color: #fff;
    padding: 0px 25px;
    padding-top: 10px;
  }
  .cttop {
    font-size: 28px;
    padding: 10px 5px;
    width: 100%;
    border-bottom: 1px solid #a2a2a2;
    padding-bottom: 20px;
  }
  .closenew {
    width: 40px;
    height: 40px;
    position: absolute;
    right: 20px;
  }
  .ctbox {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 10px 0;
    margin-bottom: 10px;
  }
  .sqbox {
    font-size: 26px;
    color: #666666;
    display: flex;
    align-items: center;
  }
  .sqboximg {
    width: 22px;
    height: 28px;
    margin: 0px 5px;
  }
  .sqname {
    width: 320px;
  }
  .sqbox .arco-switch {
    height: 32px !important;
    line-height: 32px !important;
    width: 52px;
    border-radius: 20px;
  }

  .ctboxnew {
    display: flex;
    flex-direction: column;
    margin: 15px 0;
  }
  .ctboxlabel {
    font-size: 30px;
    margin-top: 10px;
    margin: 10px 0;
  }
  .bjmenbox {
    width: 405px;

    background: #ffffff;
    border-radius: 10px 10px 10px 10px;
    margin: 10px 0;
  }
  .ctmanbox {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 10px 20px;
    overflow-y: auto;
    padding-bottom: 130px;
  }
  .bjmenboxitem {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px;
  }
  .bjmenboxitemname {
    color: #666666;
    font-size: 26px;
  }
  .bjmenboxitemnames {
    font-size: 26px;
  }
  .anto .arco-switch {
    height: 32px !important;
    line-height: 32px !important;
    width: 52px;
    border-radius: 20px;
  }

  .sxbox {
    display: flex;
    align-items: center;
    padding-left: 15px;
    flex-wrap: wrap;
  }
  .sxitem {
    width: 114px;
    height: 60px;
    line-height: 60px;
    text-align: center;
    overflow: hidden; /* 隐藏溢出的内容 */
    white-space: nowrap; /* 禁止换行 */
    text-overflow: ellipsis; /* 溢出时显示省略号 */
    font-size: 26px;
    color: #666666;
    background-color: #efefef;
    border-radius: 5px;
    padding: 0px 5px;
  }
  .bjmenboxitems {
    display: flex;
    padding-bottom: 20px;
  }
  .sxitem {
    margin: 5px;
  }
  .sxitemac {
    color: #fff;
    background-color: #5f6d7c;
  }
  .resetbox {
    width: 405px;
    height: 90px;
    background: linear-gradient(180deg, #a1b7cd 0%, #5f6d7c 100%);
    box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
    border-radius: 10px 10px 10px 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffff;
    font-size: 32px;
    position: absolute;
    top: 93%;
    left: 50%;
    transform: translate(-50%, 0);
  }
  .tsbox {
    width: 375px;
    height: 50px;
    background: #808080;
    border-radius: 10px 10px 10px 10px;
    position: absolute;
    top: 90px;
    left: 315px;
    display: flex;
    align-items: center;
    padding: 0px 14px;
    justify-content: space-between;
  }
  /* 倒三角形的样式 */
  .tsbox::before {
    content: '';
    position: absolute;
    top: -11px; /* 向上偏移，使三角形位于 div 的上边 */
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 15px solid transparent; /* 左侧透明 */
    border-right: 15px solid transparent; /* 右侧透明 */
    border-bottom: 15px solid #808080; /* 底边颜色，与 div 背景相同 */
  }
  .tsitem {
    width: 30px;
    height: 30px;

    border-radius: 50%;
  }
  .hbcbox {
    width: 121px;
    height: 220px;
    background: #808080;
    border-radius: 10px 10px 10px 10px;
    position: absolute;
    top: 90px;
    right: 125px;
    display: flex;
    align-items: center;
    flex-direction: column;
    padding: 20px 0px;
  }

  .hbcbox:before {
    content: '';
    position: absolute;
    top: -11px; /* 向上偏移，使三角形位于 div 的上边 */
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 15px solid transparent; /* 左侧透明 */
    border-right: 15px solid transparent; /* 右侧透明 */
    border-bottom: 15px solid #808080; /* 底边颜色，与 div 背景相同 */
  }
  .hbcitem {
    width: 98px;
    height: 0px;
    border-radius: 4px;
    margin: 10px 0;
  }
  .hbcbox :first-child {
    margin-top: 0px;
  }
</style>
